<?php

namespace App\Trip\Orders\BookOrders\Plane\Passengers;

use App\Trip\Code;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractOrderParam;
use App\Trip\Orders\BookOrders\Plane\Order\BookNewPlaneOrder;
use App\Trip\Orders\TripOrderState;
use App\Trip\Plane\PlaneInfo\FlightInfo;
use Exception;
use GuzzleHttp\Exception\GuzzleException;

class BookPlaneOrderPassengers
{
    private array              $passengers;
    private AbstractOrderParam $order_param;
    private BookNewPlaneOrder  $orderInfo;

    /**
     * @throws Exception
     */
    public function __construct(BookNewPlaneOrder $orderInfo)
    {
        $this->orderInfo   = $orderInfo;
        $this->passengers  = $this->orderInfo->getPassengerParam()->getParamPassengers();
        $this->order_param = $this->orderInfo->getOrderParam();

    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function buildPassengers(): array
    {
        $passengers = $this->passengers;
        collect($passengers)->where('passenger_type', 1)->pluck('mobile')->countBy()->map(function ($count, $key) {
            if ($count > 1) {
                throw new Exception("成人手机号不能重复", Code::BAD_REQUEST);
            }
        })->toArray();
        foreach ($passengers as $pk => $passenger) {
            $passenger_type                 = $passenger['passenger_type'];
            $passengers                     = $this->getPassengersCommonData($this->order_param->getTripParam()->getTripInfo(), $passengers, $pk, $passenger_type);
            $passengers[$pk]['order_state'] = TripOrderState::ORDER_STATE_WAITING_PAY;
        }
        return $passengers;
    }

    /**
     * @throws Exception
     */
    function getPassengersCommonData(FlightInfo $flight_info, mixed $passengers, int|string $pk, int $passenger_type): mixed
    {
        $passengers[$pk]['price_details'] = [];
        $passengers[$pk]['ticket_price']  = $this->calcPriceByPassengerType($flight_info, $passenger_type);
        $passengers[$pk]['construct_fee'] = $this->calcConstructionFeeByPassengerType($flight_info, $passenger_type);
        $passengers[$pk]['fuel_fee']      = $this->calcFuelFeeByPassengerType($flight_info, $passenger_type);
        $passengers[$pk]['service_fee']   = $this->getServiceFeeByPassengerType($flight_info, $passenger_type);
        $passengers[$pk]['cabin']         = $this->getCabinByPassengerType($flight_info, $passenger_type);
        return $passengers;
    }

    /**
     * 计算票价
     *
     * @throws Exception
     */
    private function calcPriceByPassengerType(FlightInfo $flight_info, int $passenger_type): float
    {
        $check_price    = $flight_info->getCheckPrices();
        $provider_price = $flight_info->getProviderPrices();
        /**
         * 类型转换
         */
        $map = [
            1 => 'adult_price',
            3 => 'child_price',
        ];

        if (!isset($map[$passenger_type])) {
            throw new Exception("航班不支持的乘客类型");
        }
        $price_key = $map[$passenger_type];
        if (!isset($check_price[$price_key])) {
            throw new Exception("航班不支持的乘客类型");
        }
        return $check_price[$price_key];
    }

    /**
     * 计算票价
     *
     * @throws Exception
     */
    private function calcConstructionFeeByPassengerType(FlightInfo $flight_info, int $passenger_type): float
    {
        $price = $flight_info->getConstructionFees();
        /**
         * 类型转换
         */
        $map = [
            1 => 'adult_construction_fee',
            3 => 'child_construction_fee',
        ];

        if (!isset($map[$passenger_type])) {
            throw new Exception("航班不支持的乘客类型");
        }
        $price_key = $map[$passenger_type];
        if (!isset($price[$price_key])) {
            throw new Exception("航班不支持的乘客类型");

        }
        return $price[$price_key];
    }

    /**
     * 计算票价
     *
     * @throws Exception
     */
    private function calcFuelFeeByPassengerType(FlightInfo $flight_info, int $passenger_type): float
    {
        $price = $flight_info->getFuelFees();
        /**
         * 类型转换
         */
        $map = [
            1 => 'adult_fuel_fee',
            3 => 'child_fuel_fee',
        ];

        if (!isset($map[$passenger_type])) {
            throw new Exception("航班不支持的乘客类型");
        }
        $price_key = $map[$passenger_type];
        if (!isset($price[$price_key])) {
            throw new Exception("航班不支持的乘客类型");

        }
        return $price[$price_key];
    }

    /**
     * @throws Exception
     */
    private function getServiceFeeByPassengerType(FlightInfo $flight_info, int $passenger_type)
    {
        $check_price    = $flight_info->getCheckPrices();
        $provider_price = $flight_info->getProviderPrices();
        /**
         * 类型转换
         */
        $map = [
            1 => 'adult_price',
            3 => 'child_price',
        ];

        if (!isset($map[$passenger_type])) {
            throw new Exception("航班不支持的乘客类型");
        }
        $price_key = $map[$passenger_type];
        if (!isset($check_price[$price_key]) || !isset($provider_price[$price_key])) {
            throw new Exception("航班不支持的乘客类型");
        }

        // 结算价小于供货价
        $service_fee = $check_price[$price_key] - $provider_price[$price_key];
        if ($service_fee < 0) {
            throw new Exception("价格有误");
        }
        return $service_fee;
    }

    /**
     * @throws Exception
     */
    private function getCabinByPassengerType(FlightInfo $flight_info, int $passenger_type)
    {
        $cabins = $flight_info->getCabins();
        /**
         * 类型转换
         */
        $map = [
            1 => 'adult',
            3 => 'child',
        ];
        if (!isset($map[$passenger_type])) {
            throw new Exception("航班不支持的乘客类型");
        }
        $cabin_key = $map[$passenger_type];
        if (!isset($cabins[$cabin_key])) {
            throw new Exception("航班不支持的乘客类型");

        }
        return $cabins[$cabin_key];
    }
}